/* register_word.c COPYRIGHT KIC LIMITED 2011 
 *
 * Date         Corp.   Name           Note
 * ---------- ------- ------------ -------------------
 * 2011.10.25 KIC      J.TANAKA      First Modification
 */


#ifdef DEBUG /* デバッグ用コードの開始 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <ctype.h> 
#include "common.h"


/* global var */
char rbuf[BUFFSIZE];



wlist_t *wtop = (wlist_t *)NULL;
/* functions */
int register_word(int npage, char *wordp);
void display(wlist_t *wlp);
void print_plist(plist_t *plp);
char *tolower_str(char *wordp);

/* test register_word */
main(){
	//call register_word()
	int ret;
	ret = register_word(3, "test");
	ret = register_word(3, "1test");
	
	ret = register_word(3, "test");
	ret = register_word(4, "test");
	ret = register_word(4, "APPLE");
	ret = register_word(7, "fukuda");
	ret = register_word(9, "chou");
	ret = register_word(99, "teki");
	ret = register_word(583, "tanaka");
	ret = register_word(383, "koyama");

	display(wtop);

	return EXIT_SUCCESS;

}
void display(wlist_t *wlp){
	if(wlp != NULL){
		display(wlp->leftp); /* 左子ノードへポインタを渡して表示する */
		print_word(wlp);     /* 自身を表示する */  
		display(wlp->rightp);/* 右子ノードへポインタを渡して表示する */
	}
}

void print_word(wlist_t *wlp){
	printf("\"%s\"\t", wlp->wordp); /* 単語を表示する */
	print_plist(wlp->top);          /* ページを表示する */
	printf("\n");                   /* 改行 */
}

void print_plist(plist_t *plp){
	plist_t *thispage;/* 現在着目しているページ */
        /* plist_tに登録されているページ番号が存在する間、繰り返す*/
	for(thispage = plp; thispage != NULL; thispage = thispage->nextp){
		printf("%d," , thispage->pnum);
	}
}
#else /* デバッグ用コードの終了 */

#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <ctype.h> 

#endif

/* function */
int register_word(int npage, char *wordp){

   plist_t *plp; /* ページを登録する構造体へのポインタ */
   wlist_t *wlp; /* 単語を登録する構造体へのポインタ */
   int wcomp;    /* 比較結果 */
   wlist_t *wlorgp; /* 単語リストを辿る際に用いるポインタ */

   /* 先頭が数字の単語は登録しない */
   if(isdigit(*wordp)){return 1;}
   /* 大文字を小文字に変換 */
   wordp = tolower_str(wordp); 
   /* 単語の最大長を超える場合は、最後の文字を"-"に置き換える */
   if(strlen(wordp)>WORDFIELDLENGTH){
	(*(wordp+WORDFIELDLENGTH -1)) = '-';
	(*(wordp+WORDFIELDLENGTH)) = '\0';
   }
     
   if(wtop == (wlist_t *)NULL){ /* 単語登録表に、まだ単語が未登録の場合 */
      plp = (plist_t *)malloc(sizeof(plist_t));
      if( plp == (plist_t *)NULL){ /* 確保できなければエラーメッセージを表示する */
         printf(ERR_01011);
         exit(1);
      }
      plp->nextp = (plist_t *)NULL;
      plp->pnum = npage;
      wlp = (wlist_t *)malloc(sizeof(wlist_t));
      if(wlp == (wlist_t *)NULL){
         free(plp); /* 確保できなければplpを解放する */
         printf(ERR_01011);
         exit(1);
      }
      wlp->up = (wlist_t *)NULL;
      wlp->leftp = (wlist_t *)NULL;
      wlp->rightp = (wlist_t *)NULL;
      wlp->wordp = wordp;
      wlp->top = plp;
      wlp->lastp = plp;

      wtop = wlp;
      return 0;

   }else{
      wlorgp = wtop;
      while(wlorgp != (wlist_t *)NULL){
         wcomp = strcmp(wordp, wlorgp->wordp); /* 着目している単語と登録しようとしている単語を比較する */
         if(wcomp < 0){                        /* 登録しようとしている単語の方が前のとき */
            if(wlorgp->leftp == (wlist_t *)NULL){
               plp = allocp();
               wlp = allocw();
               wlp->top = plp;
               wlp->lastp = plp;
               wlp->wordp = wordp;
               plp->pnum = npage;
               wlorgp->leftp = wlp;
               wlp->up = wlorgp;
               return 0;
            }else{
               wlorgp = wlorgp->leftp;
            }
         }else if(wcomp > 0){ /* 登録しようとしている単語の方が後ろのとき */
            if(wlorgp->rightp == (wlist_t *)NULL){
               plp = allocp();
               wlp = allocw();
               wlp->top = plp;
               wlp->lastp = plp;
               wlp->wordp = wordp;
               plp->pnum = npage;
               wlorgp->rightp = wlp;
               wlp->up = wlorgp;
               return 0;
            }else{
               wlorgp = wlorgp->rightp;
            }
         }else{ /* wcomp == 0: 同じ単語が既に登録されている時  */
            if(wlorgp->lastp->pnum == npage){
               free(wordp);
               return 0;
            }else{
               plp = allocp();
               plp->pnum = npage;
               wlorgp->lastp->nextp = plp;
               wlorgp->lastp = plp;
               return 0;
            }
         }
      }
   }
   return 0;
}


plist_t *allocp(void){
	plist_t *plp;
	
	plp = (plist_t *)malloc(sizeof(plist_t));
	if(plp == (plist_t *)NULL){
		printf(ERR_01011);
		return ((plist_t *)NULL);
	}
	plp->nextp = (plist_t *)NULL;
	plp->pnum = 0;

	return (plp);

}

/* wlist_tの領域を動的に確保
*args
* なし
*Return Value
* 確保した領域へのポインタ
*/
wlist_t *allocw(void){
	wlist_t *wlp;
	wlp = (wlist_t *)malloc(sizeof(wlist_t));
	if(wlp == (wlist_t *)NULL){
		printf(ERR_01011);
		return ((wlist_t *)NULL);
	}
	wlp->up = (wlist_t *)NULL;
	wlp->rightp = (wlist_t *)NULL;
	wlp->leftp = (wlist_t *)NULL;

	return (wlp);
}
/* 大文字から小文字への変換
*args
* wordp 単語へのポインタ
*Return Value
* 変換後の単語へのポインタ
*/
char *tolower_str(char *wordp){
	char buf[BUFFSIZE];
	char *bufp;
	int i;
	char ch;
       
	memset(buf, '\0', BUFFSIZE);/* バッファの初期化 */	
	for(i=0; *wordp != '\0'; wordp++){/* 単語の末尾まで小文字に変換 */
		ch =  tolower(*wordp);
		buf[i++] = ch;
	}
        bufp = (char *)malloc(strlen(buf)+1);
 	strcpy(bufp, buf);

	return (bufp);
}

